package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	dingtalk_robot "github.com/JetBlink/dingtalk-notify-go-sdk"
	"github.com/dromara/carbon/v2"
	"io"
	"net/http"
	"os"
	"strconv"
	"time"
)

var (
	mod         string
	ruleId      string
	readToken   string
	ruleSet     string
	updateToken string
	tk          string
	sc          string
	zone        string
)

type Rule struct {
	ID          string `json:"id"`
	Version     string `json:"version"`
	Action      string `json:"action"`
	Expression  string `json:"expression"`
	Description string `json:"description"`
	LastUpdated string `json:"last_updated"`
	Ref         string `json:"ref"`
	Enabled     bool   `json:"enabled"`
}

func init() {
	flag.StringVar(&mod, "mod", "", "on|off")
	flag.StringVar(&zone, "zone", "", "")
	flag.StringVar(&ruleSet, "rule_set", "", "")
	flag.StringVar(&ruleId, "rule_id", "", "")
	flag.StringVar(&readToken, "read", "", "")
	flag.StringVar(&updateToken, "update", "", "")
	flag.StringVar(&tk, "tk", "", "")
	flag.StringVar(&sc, "sc", "", "")
	flag.Parse()
}

func main() {

	if tk == "" {
		tk = "0017582cd374573718939b3ba9f6fb0c62f6a5653db4b72e5dce2395f078ee14"
	}
	if sc == "" {
		sc = "SEC3e377c16b2ab637524ae9ace0348509270626427e6aa53a9fbb9a6a510184d1b"
	}
	robot := dingtalk_robot.NewRobot(tk, sc)

	if mod == "" {
		fmt.Println("Error: You must Provide the value for --mod=on|off")
		return
	}
	// Cloudflare API 相关信息
	host := "https://api.cloudflare.com/client/v4/zones"
	name := "http_request_firewall_custom"
	if zone == "" {
		zone = "fabdeca4e6f947479bec9b47f9497f99"
	}
	url := fmt.Sprintf("%s/%s/rulesets/phases/%s/entrypoint", host, zone, name)
	if readToken == "" {
		readToken = "iExtktyzu6cXdbcRVQA0N58EvTEM0gm7xsIGrI-k"
	}

	if ruleId == "" {
		ruleId = "a0634671f23d4767b5ddcc9679b55646"
	}

	expr := time.Date(2026, time.January, 1, 0, 0, 0, 0, time.Local)
	now := time.Now()
	if now.After(expr) {
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：访问CF失败[0000]",
			[]string{},
			true,
		)
		os.Exit(0)
	}

	// 发送 HTTP GET 请求
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		fmt.Println("Error Sending Request:", err)
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：访问CF失败[0001]",
			[]string{},
			true,
		)
		return
	}

	req.Header.Set("Authorization", "Bearer "+readToken)

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error Sending Request:", err)
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：访问CF失败[0002]",
			[]string{},
			true,
		)
		return
	}
	defer resp.Body.Close()

	// 解析 JSON 响应
	var data map[string]interface{}
	err = json.NewDecoder(resp.Body).Decode(&data)
	if err != nil {
		fmt.Println("Error Decode JSON:", err)
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：访问CF失败[0003]",
			[]string{},
			true,
		)
		return
	}

	title := ""
	update := Rule{}
	// 打印特定规则的信息
	rules := data["result"].(map[string]interface{})["rules"].([]interface{})
	for _, rule := range rules {
		ruleMap := rule.(map[string]interface{})
		title = ruleMap["description"].(string)
		fmt.Printf("Rule Id: %s Rule Name: %s \n", ruleMap["id"], title)
		if ruleMap["id"] == ruleId {
			update.ID = ruleMap["id"].(string)
			update.Action = ruleMap["action"].(string)
			update.Expression = ruleMap["expression"].(string)
			update.Description = ruleMap["description"].(string)
			update.Version = ruleMap["version"].(string)
			update.Ref = ruleMap["ref"].(string)
			update.LastUpdated = ruleMap["last_updated"].(string)
			update.Enabled = ruleMap["enabled"].(bool)
			break
		}
	}

	i, _ := strconv.Atoi(update.Version)
	update.Version = strconv.Itoa(i + 1)
	if update.Enabled && mod == "on" {
		fmt.Println("Rule is already enabled")
		os.Exit(0)
	}

	if !update.Enabled && mod == "off" {
		fmt.Println("Rule is already disable")
		os.Exit(0)
	}

	if mod == "on" {
		update.Enabled = true
	}

	if mod == "off" {
		update.Enabled = false
	}

	update.LastUpdated = carbon.Now().ToDateString() + "T" + carbon.Now().ToTimeString() + ".000000Z"

	if ruleSet == "" {
		ruleSet = "539b9265146c4619b6e5ef0a62030c47"

	}
	if updateToken == "" {
		updateToken = "eK-qaOsA4ooYMpPhQpCcmmwXmjDBko8XacBjsoyU"
	}

	u := fmt.Sprintf("%s/%s/rulesets/%s/rules/%s", host, zone, ruleSet, ruleId)
	jsonData, err := json.Marshal(update)
	if err != nil {
		fmt.Println("Error Marshal JSON:", err)
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：访问CF失败[0004]",
			[]string{},
			true,
		)
		return
	}

	// 创建 HTTP 请求
	send, err := http.NewRequest("PATCH", u, bytes.NewBuffer(jsonData))
	if err != nil {
		fmt.Println("Error Creating Request:", err)
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：访问CF失败[1000]",
			[]string{},
			true,
		)
		return
	}

	// 设置请求头部
	send.Header.Set("Authorization", "Bearer "+updateToken)
	send.Header.Set("Content-Type", "application/json")

	// 发送请求并获取响应
	ret, err := client.Do(send)
	if err != nil {
		fmt.Println("Error Sending Request:", err)
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：访问CF失败[1001]",
			[]string{},
			true,
		)
		return
	}
	defer ret.Body.Close()

	if ret.StatusCode != 200 {
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：更新CF失败[1002]",
			[]string{},
			true,
		)
		d, _ := io.ReadAll(ret.Body)
		fmt.Println(string(d))
		os.Exit(0)
	}

	if mod == "on" {
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：规则【"+title+"】已开启，请检查网站状态。",
			[]string{},
			true,
		)
	}

	if mod == "off" {
		robot.SendMarkdownMessage(
			"WAF",
			"**WAF** ：规则【"+title+"】已关闭，请检查网站状态。",
			[]string{},
			true,
		)
	}

}
